/**
 * jims
 */
package com.jims.master.modules.drug.service;

import com.jims.master.common.data.StringData;
import com.jims.master.common.persistence.Page;
import com.jims.master.common.service.CrudService;
import com.jims.master.common.utils.ChineseCharToEnUtils;
import com.jims.master.common.utils.PrintPdfUtils;
import com.jims.master.common.web.impl.BaseDto;
import com.jims.master.modules.drug.dao.*;
import com.jims.master.modules.drug.entity.*;
import com.jims.master.modules.sys.dao.CompanyDao;
import com.jims.master.modules.sys.entity.User;
import com.jims.master.modules.sys.utils.DeptUtils;
import com.jims.master.modules.sys.utils.DictUtils;
import com.jims.master.modules.sys.utils.UserUtils;
import com.jims.master.modules.utils.BloodUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 药品采购计划Service
 * @author DT
 * @version 2017-03-22
 */
@Service
@Transactional(readOnly = true)
public class DrugBuyPlanService extends CrudService<DrugBuyPlanDao, DrugBuyPlan> {
    @Autowired
    private DrugBuyPlanDao drugBuyPlanDao;
    @Autowired
    private DrugSupplierCataService drugSupplierCataService;
    @Autowired
    private DrugStorageDeptDao drugStorageDeptDao;
    @Autowired
    private DrugImportMasterService drugImportMasterService;
    @Autowired
    private DrugInfoDao drugInfoDao;
    @Autowired
    private DrugImportMasterDao drugImportMasterDao;
    @Autowired
    private DrugImportDetailDao drugImportDetailDao;
    @Autowired
    private DrugStockDao drugStockDao;
    @Autowired
    private CompanyDao companyDao;

    /**
     * 自动生成采购计划药品名称补全
     * @param drugInfo
     * @param orgId
     * @return
     * @author fengyg
     * @date 2017-03-17
     */
    public List<DrugBuyPlan> autoBuyPlanDrugInfo(DrugInfo drugInfo, String orgId, String q, String limit) {
        List<DrugBuyPlan> drugBuyPlans = dao.autoBuyPlanDrugInfo(drugInfo, orgId, q, limit, UserUtils.getUser().getOrgDept().getId());
        return drugBuyPlans;
    }

    /**
     * 保存药品采购计划(生成)
     * @param drugBuyPlan
     * @return
     * @author fengyg
     */
    @Transactional(readOnly = false)
    public int saveDrugBuyPlanCreate(DrugBuyPlan drugBuyPlan){
        int num = 0;
        if(null != drugBuyPlan){
            List<DrugBuyPlan> list = drugBuyPlan.getDrugBuyPlanList();
            String buyPlanNum = getBuyPlanNum();
            if(null != list && list.size() > 0){
                for (DrugBuyPlan buyPlan : list) {
                    DrugBuyPlan insertData = buyPlan;
                    insertData.preInsert();
                    insertData.updateOrgId();
                    insertData.setPurchaseNumber(buyPlanNum);
                    insertData.setStorageDept(UserUtils.getUser().getOrgDept().getId());
                    insertData.setCostPrice(buyPlan.getDrugPrice().getTradePrice() + "");
                    insertData.setWarehouseKeeper(UserUtils.getUser().getId());
                    insertData.setStateFlag("0");
                    int insert = dao.insert(insertData);
                    if(insert > 0){
                        num += insert;
                    }else{
                        return 0;
                    }
                }
            }
        }
        return num;
    }

    /**
     * 保存或调整药品采购计划
     * @param drugBuyPlan
     * @return
     * @author fengyg
     */
    @Transactional(readOnly = false)
    public StringData saveOrUpdateDrugBuyPlan(DrugBuyPlan drugBuyPlan,String stateFlag) {
        StringData data = new StringData();
        if(null != drugBuyPlan){
            List<DrugBuyPlan> buyPlanList = drugBuyPlan.getDrugBuyPlanList();
            int num = 0;
            if (null != buyPlanList && buyPlanList.size() > 0) {
                for(int i = 0; i < buyPlanList.size(); i++){
                    DrugBuyPlan buyPlan = buyPlanList.get(i);
                    buyPlan.setPurchaseOrder((i+1) + "");
                    buyPlan.setStorageDept(UserUtils.getUser().getOrgDept().getId());
                    buyPlan.setStateFlag(stateFlag);
                    buyPlan.updateOrgId();
                    if(null == buyPlan.getId() || buyPlan.getId().equals("")){
                        buyPlan.preInsert();
                        num += dao.insert(buyPlan);
                    }else{
                        buyPlan.preUpdate();
                        num += dao.update(buyPlan);
                    }
                }
                if (num > 0) {
                    data.setCode("success");
                    data.setData("保存成功!");
                }
            } else {
                data.setCode("error");
                data.setData("没有要保存的数据!");
            }
        }else{
            data.setCode("error");
            data.setData("没有要保存的数据!");
        }
        return data;
    }

    /**
     * 采购药品入库
     * @param drugBuyPlan
     * @return
     * @author fengyg
     */
    @Transactional(readOnly = false)
    public int saveImportBuyPlan(DrugBuyPlan drugBuyPlan){
        int num = 0;
        if(null != drugBuyPlan){
            if(drugBuyPlan.getDrugBuyPlanList().size() > 0){
                //拼装入库主记录
                DrugImportMaster importMaster = new DrugImportMaster();
                importMaster.preInsert();
                importMaster.updateOrgId();
                importMaster.setStorageId(UserUtils.getUser().getOrgDept().getId());
                importMaster.setDocumentNo(drugImportMasterService.createDocumentNo(importMaster));
                importMaster.setImportDate(new Date());
                importMaster.setSupplier(drugBuyPlan.getDrugBuyPlanList().get(0).getSupplierId());
                importMaster.setImportClass("采购");
                Double accountReceivable = 0.00;    //应付款
                for (DrugBuyPlan buyPlan : drugBuyPlan.getDrugBuyPlanList()) {
                    DrugInfo info = drugInfoDao.get(buyPlan.getInfoId());
                    //拼装入库明细
                    DrugImportDetail importDetail = new DrugImportDetail();
                    importDetail.preInsert();
                    importDetail.setMasterId(importMaster.getId());
                    importDetail.setItemNo(buyPlan.getPurchaseOrder());
                    importDetail.setDrugCode(buyPlan.getDrugCode());
                    importDetail.setInfoId(buyPlan.getInfoId());
                    importDetail.setPackageNum(info.getPackageNum() + "");
                    importDetail.setPackageSpec(buyPlan.getPackageSpec());
                    importDetail.setPackageUnits(buyPlan.getPackageUnit());
                    importDetail.setMinSpec(info.getMinSpec());
                    importDetail.setMinUnits(info.getMinUnits());
                    importDetail.setPurchasePrice(buyPlan.getCostPrice());
                    importDetail.setDiscount("1");
                    importDetail.setBatchNo(buyPlan.getBatchNo());
                    importDetail.setExpireDate(buyPlan.getExpireDate());
                    importDetail.setQuantity((Double.valueOf(buyPlan.getPurchaseSelling()) * info.getPackageNum()) + "");
                    importDetail.updateOrgId();
                    int i = drugImportDetailDao.insert(importDetail); //保存采购入库明细
                    accountReceivable += Double.valueOf(buyPlan.getPurchaseSelling()) * Double.valueOf(buyPlan.getCostPrice());
                    if(i > 0){
                        num += i;
                    }else{
                        return 0;
                    }
                    //判断一个库存的，一个药品的批号是否存在，若存在，直接加数量
                    DrugStock newStock = new DrugStock();
                    newStock.preInsert();
                    newStock.setDrugCode(buyPlan.getDrugCode());
                    newStock.setInfoId(buyPlan.getInfoId());
                    newStock.setStorageId(UserUtils.getUser().getOrgDept().getId());
                    newStock.setBatchNo(buyPlan.getBatchNo());
                    newStock.updateOrgId();
                    List<DrugStock> oldStockList = drugStockDao.findByBatchNo(newStock);
                    if(null != oldStockList && oldStockList.size() > 0){   //同批号药品已经存在
                        DrugStock oldStock = oldStockList.get(0);
                        //新库存数量 = 入库的大包装数量 * 包装数 + 已有库存量
                        Double newQuantity = Double.valueOf(buyPlan.getPurchaseSelling()) * Double.valueOf(info.getPackageNum()) + oldStock.getQuantity();
                        oldStock.setQuantity(newQuantity);
                        oldStock.setDocumentNo(importMaster.getDocumentNo());
                        oldStock.setImportMasterId(importMaster.getId());
                        oldStock.setPurchasePrice(Double.valueOf(buyPlan.getCostPrice()));
                        oldStock.setExpireDate(buyPlan.getExpireDate());
                        oldStock.preUpdate();
                        int update = drugStockDao.update(oldStock);   //更新库存
                        if(update > 0){
                            num += update;
                        }else{
                            return 0;
                        }
                    }else{
                        newStock.setPackageNum(info.getPackageNum() + "");
                        newStock.setPackageSpec(info.getPackageSpec());
                        newStock.setPackageUnits(info.getPackageUnit());
                        newStock.setMinSpec(info.getMinSpec());
                        newStock.setMinUnits(info.getMinUnits());
                        newStock.setPurchasePrice(Double.valueOf(buyPlan.getCostPrice()));
                        newStock.setDiscount("1");
                        newStock.setExpireDate(buyPlan.getExpireDate());
                        newStock.setQuantity(Double.valueOf(buyPlan.getPurchaseSelling()) * Double.valueOf(info.getPackageNum()));
                        newStock.setDocumentNo(importMaster.getDocumentNo());
                        newStock.setImportMasterId(importMaster.getId());
                        int insert = drugStockDao.insert(newStock);  //插入库存
                        if(insert > 0){
                            num += insert;
                        }else{
                            return 0;
                        }
                    }
                    //更新采购单状态
                    buyPlan.setBuyer(UserUtils.getUser().getId());  //采购员
                    buyPlan.setStateFlag("4");
                    buyPlan.updateOrgId();
                    int flag = dao.updateStateFlag(buyPlan);
                    if(flag > 0){
                        num += flag;
                    }else{
                        return 0;
                    }
                }
                importMaster.setAccountReceivable(accountReceivable);
                int i = drugImportMasterDao.insert(importMaster); //保存采购入库主记录
                if(i > 0){
                    num += i;
                }else{
                    return 0;
                }
            }else{
                return 0;
            }
        }else{
            return 0;
        }
        return num;
    }

    /**
     * 根据采购单号获取需要调整的采购单数据
     * @param drugBuyPlan
     * @return
     * @author fengyg
     */
    public Page<DrugBuyPlan> getDrugPlanList(DrugBuyPlan drugBuyPlan){
        Page<DrugBuyPlan> page = new Page<DrugBuyPlan>();
        drugBuyPlan.updateOrgId();
        drugBuyPlan.setPage(page);
        List<DrugBuyPlan> list = drugBuyPlanDao.getListByPlanNum(drugBuyPlan);
        if(null != list && list.size() > 0){
            for (DrugBuyPlan buyPlan : list) {
                if(null == buyPlan.getPurchaseSelling() || "".equals(buyPlan.getPurchaseSelling())){
                    buyPlan.setPurchaseSelling(buyPlan.getPlannedSelling());
                    buyPlan.setPurchaseAmount(buyPlan.getPlannedAmount());
                }
            }
        }
        page.setList(list);
        return page;
    }

    public DrugBuyPlan get(String id) {
        return super.get(id);
    }
    public DrugBuyPlan findByNumber(DrugBuyPlan drugBuyPlan) {
        return drugBuyPlanDao.findByNumber(drugBuyPlan);
    }

    public List<DrugBuyPlan> findList(DrugBuyPlan drugBuyPlan) {
        return super.findList(drugBuyPlan);
    }

    public Page<DrugBuyPlan> findPage(Page<DrugBuyPlan> page, DrugBuyPlan drugBuyPlan) {
        return super.findPage(page, drugBuyPlan);
    }

    @Transactional(readOnly = false)
    public int save(DrugBuyPlan drugBuyPlan) {
        return super.save(drugBuyPlan);
    }

    @Transactional(readOnly = false)
    public int delete(DrugBuyPlan drugBuyPlan) {
        return dao.delete(drugBuyPlan);
    }

    /**
     * 生成采购单的单据号
     * @return
     * @author fengyg
     */
    public String getBuyPlanNum(){
        String deptName = DeptUtils.getDeptName(UserUtils.getUser().getOrgDept().getId(),"");
        deptName = ChineseCharToEnUtils.getAllFirstLetter(deptName);
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return deptName + dateFormat.format(new Date());
    }

    /**
     * 根据采购单状态获取采购单据号
     * @param stateFlag 采购单状态
     * @return
     * @author fengyg
     */
    public List<DrugBuyPlan> getBuyPlanNum(String stateFlag){
        DrugStorageDept storage = drugStorageDeptDao.getByStorageCode(UserUtils.getUser().getOrgDept().getId());
        if(null != storage && !storage.getStorageType().equals("0")){
            return drugBuyPlanDao.getBuyPlanNum(stateFlag, UserUtils.getOrgId(), storage.getStorageCode());
        }else{
            return drugBuyPlanDao.getBuyPlanNum(stateFlag,UserUtils.getOrgId(),null);
        }
    }

    /**
     * 药品采购执行打印
     * @param drugBuyPlan
     * @return
     */
    public String drugPlanPrint(DrugBuyPlan drugBuyPlan){
        User user = UserUtils.getUser();
        drugBuyPlan.setStateFlag("3");
        String title="药品采购单据";
        List<BaseDto> list=dao.getDrugPlanListPrint(drugBuyPlan);
        Map map = new HashMap();
        Double totalPrice=0.0;
        if(list.size()>0){
            map.put("warehouseKeeper",BloodUtils.getNameByUserId(list.get(0).getAsString("warehouseKeeper")));
            map.put("purchaseNumber",list.get(0).getAsString("purchaseNumber"));
            int i=1;
            for(BaseDto detail:list){
                DrugSupplierCata drugSupplierCata=drugSupplierCataService.get(detail.getAsString("vedorName"));
                if(drugSupplierCata!=null){
                    detail.put("vedorName",drugSupplierCata.getSupplierJc());
                }
                totalPrice+=Double.parseDouble(detail.getAsString("purchaseAmount"));
                detail.put("index",Integer.toString(i++));
                Pattern pattern = Pattern.compile("-?[0-9]+.?[0-9]+");
                Matcher isNum = pattern.matcher(detail.getAsString("packageUnit"));
                if (isNum.matches()) {
                    detail.put("packageUnit", DictUtils.getDictLabel(detail.getAsString("packageUnit"), "SPEC_UNIT", ""));
                }
            }
        }
        String hospital = UserUtils.getUser().getCompany().getOrgName();
        map.put("title",title);
        map.put("totalPrice",String.format("%.2f", totalPrice));
        map.put("hospital",hospital);
        map.put("lists",list);
        String printPath = PrintPdfUtils.previewPdf(user.getId(), "his/drug/drugPlanPrint.jasper", map, list, "drugPlanPrint");
        return  printPath;
    }
    /**
     * 采购药品入库换厂商换药自动补全查询
     * @param q
     * @param drugCode
     * @param limit
     * @return
     * @author CTQ
     */
    public List<BaseDto> findListByParam(String q, String drugCode, String limit){
        return dao.findListByParam(q,drugCode,limit,UserUtils.getOrgId());
    }
}